package com.jt.www.admin.order_pc.service.impl;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jt.www.admin.market.service.CommissionService;
import com.jt.www.admin.market.service.MarketerInfoService;
import com.jt.www.admin.order_pc.service.OfflineOrderService;
import com.jt.www.admin.order_pc.service.OrgMarketerService;
import com.jt.www.admin.user.service.RegisterCustomerService;
import com.jt.www.biz.order_pc.service.EndorseService;
import com.jt.www.biz.user_wxb.service.WeChatAppLoginService;
import com.jt.www.common.service.AttrConfigService;
import com.jt.www.common.service.PolicyAttributeService;
import com.jt.www.dao.mapper.offline.OfflineMapper;
import com.jt.www.dao.mapper.offline.OfflineOrderMapper;
import com.jt.www.dao.mapper.offline.OfflinePolicyMapper;
import com.jt.www.dao.mapper.offline.OfflineUserMapper;
import com.jt.www.domain.bo.OfflineOrderBO;
import com.jt.www.domain.dto.AreaDto;
import com.jt.www.domain.dto.OfflineOrderInputDTO;
import com.jt.www.domain.dto.OfflineProductDTO;
import com.jt.www.domain.dto.OfflineRegisterDTO;
import com.jt.www.domain.enums.common.*;
import com.jt.www.domain.enums.pc.MarketerChannelCodeEnum;
import com.jt.www.domain.enums.pc.OfflineAddCompanyEnum;
import com.jt.www.domain.enums.pc.OfflineGDProductEnum;
import com.jt.www.domain.enums.pc.OfflineUserTypeEnum;
import com.jt.www.domain.po.*;
import com.jt.www.domain.qo.MarketerInfoQO;
import com.jt.www.domain.qo.OfflineOrderQO;
import com.jt.www.domain.qo.OfflinePolicyQO;
import com.jt.www.domain.qo.SavePolicyDetailFileQo;
import com.jt.www.domain.vo.FileVO;
import com.jt.www.domain.vo.OfflineOrderVo;
import com.jt.www.domain.vo.OfflineRegisterVo;
import com.jt.www.domain.vo.RiskDutyLimitVO;
import com.jt.www.model.conver.invoice.AttachmentVO;
import com.jt.www.model.policyattribute.PolicyAttributeEntity;
import com.jt.www.model.registerCustomer.RegisterCustomer;
import com.jt.www.model.registerCustomer.vo.ManagerInfoVo;
import com.jt.www.model.reps.GenericDataResponse;
import com.jt.www.model.reps.GenericListResponse;
import com.jt.www.model.vo.endorse.ExcelFileDetailVo;
import com.jt.www.model.vo.woxuebao.TbParamVO;
import com.jt.www.model.woxuebao.Risk.ContextRiskMap;
import com.jt.www.model.woxuebao.Risk.LimitValue;
import com.jt.www.model.woxuebao.Risk.RiskDTO;
import com.jt.www.model.woxuebao.toubao.*;
import com.jt.www.remote.*;
import com.jt.www.remote.woxuebao.InsOrderClient;
import com.jt.www.util.ChangeUtils;
import com.jt.www.util.DateUtils;
import com.jt.www.util.JsonUtils;
import com.jt.www.util.MyStringUtils;
import config.FeignConfiguration;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import tk.mybatis.mapper.weekend.Weekend;
import tk.mybatis.mapper.weekend.WeekendCriteria;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.jt.www.util.DateUtils.*;

/**
 * Created by shaoyn on 2020/05/22.
 */
@Service
public class OfflineOrderServiceImpl implements OfflineOrderService {

    public static final Logger log = LoggerFactory.getLogger(OfflineOrderServiceImpl.class);

    private final static String SYS_CODE = "sys_edu_man";
    private final static String CHANNEL_CODE = "edu";
    private final static String OFFLINE_POLICY_LIST_QUERY = "{\"channel\":\"edu\",\"pn\":1,\"ps\":1000,\"clientNoList\":[\"offline\"]}";

    @Autowired
    AttrConfigService attrConfigService;
    @Autowired
    PolicyAttributeService policyAttributeService;
    @Autowired
    CommissionService commissionService;
    @Autowired
    EndorseService endorseService;
    @Autowired
    private OfflineMapper offlineMapper;
    @Autowired
    private OfflineOrderMapper offlineOrderMapper;
    @Autowired
    private OfflinePolicyMapper offlinePolicyMapper;
    @Autowired
    private OfflineUserMapper offlineUserMapper;
    @Autowired
    private ParserClient parserClient;
    @Autowired
    private UserClient userClient;
    @Autowired
    private ProductClient productClient;
    @Autowired
    private InsOrderClient insOrderClient;
    @Autowired
    private IdgClient idgClient;
    @Autowired
    private OrgMarketerService orgMarketerService;
    @Autowired
    private RegisterCustomerService registerCustomerService;
    @Autowired
    private MarketerInfoService marketerInfoService;
    @Autowired
    private WeChatAppLoginService weChatAppLoginService;

    @Autowired
    private SttlManClient sttlManClient;

    @Autowired
    private BmsClient bmsClient;

    @Override
    @Transactional
    public ResponseEntity saveOfflineOrder(String findCode, OfflineOrderInputDTO offlineOrderInputDTO) throws Exception {
        String userType = offlineOrderInputDTO.getUserType();
        //如果前端没有传就查数据库
        if (StringUtils.isBlank(userType)) {
            userType = getUserTypeByProductCode(offlineOrderInputDTO.getProductCode());
        }
        if (StringUtils.isBlank(userType)) {
            log.info("{} 该产品:{}({})没有配置用户类型信息", findCode, offlineOrderInputDTO.getProductName(), offlineOrderInputDTO.getProductCode());
            return GenericDataResponse.errorWithMsg("该产品没有配置用户类型信息, 请联系管理人员!");
        }
        log.info("{} 该产品:{}({})配置用户类型为{}", findCode, offlineOrderInputDTO.getProductName(), offlineOrderInputDTO.getProductCode(), userType);

        offlineOrderInputDTO.setUserType(userType);

        log.info("{} 线下录入保存开始, 入参：{}", findCode, JSON.toJSONString(offlineOrderInputDTO));
        //从清单服务中心读取保单信息
        String policyFile = offlineOrderInputDTO.getPolicyFile();
        List<FileVO> policyFiles;
        try {
            policyFiles = JSON.parseArray(policyFile, FileVO.class);
        } catch (Exception e) {
            log.info("{} 保单文件json格式不正确,{}", findCode, policyFile);
            return GenericDataResponse.errorWithMsg("保单文件json格式不正确!");
        }

        OfflineOrder offlineOrder = offlineOrderInputDTO.changeToOfflineOrder();
        //录入时间
        offlineOrder.setInputTime(new Date());
        int n = offlineOrderMapper.insertSelective(offlineOrder);
        if (n < 1) {
            log.info("{} 订单保存失败", findCode);
            return GenericDataResponse.errorWithMsg("保存失败!");
        }

        //通过文件id集合得到对应清单解析的结果数据集，并迭代插入数据库
        List<OfflinePolicy> offlinePolicies = getOfflinePolicyByFiles(findCode, policyFiles);
        for (OfflinePolicy offlinePolicy : offlinePolicies) {
            offlinePolicy.setOrderId(offlineOrder.getId());
            //保存的时候需要判断每个保单是否跨期，并置状态位
            Date startDate = offlinePolicy.getStartDate();
            Date insureDate = offlinePolicy.getInsureDate();
            checkBacklogAsCrossTerm(offlinePolicy,insureDate,startDate);
            offlinePolicyMapper.insertSelective(offlinePolicy);
        }

        return GenericDataResponse.ok();
    }

    /**
     * 判断清单保单中是否有倒签以及跨期
     * @param offlinePolicy  保单数据
     * @param insureDate  出单日期
     * @param startDate 保险起期
     * @return
     */
    public OfflinePolicy checkBacklogAsCrossTerm(OfflinePolicy offlinePolicy,Date insureDate,Date startDate) throws Exception {
        if(insureDate.after(startDate)){
            offlinePolicy.setBackLog(IsOrNotEnum.IS.getValue());
        }else{
            offlinePolicy.setBackLog(IsOrNotEnum.NO.getValue());
        }
        //判断当前时间和签单日期是否是同一月份，不同月份说明需要判断跨期
        if (!DateUtils.isSameMonth(new Date(), offlinePolicy.getInsureDate())) {
            //根据签单日期查询业管跨期区间 签单日期需要格式化成类似 ：202103
            GenericListResponse intertermporalDate = getIntertemporal(offlinePolicy.getInsureDate());
            if(intertermporalDate.getList()==null){
                log.info("未获取到跨期区间");
            }
            //从业管里面获取跨期起期和止期
            if(intertermporalDate.getList()!=null){
                //拿当前时间也就是录单时间，在业管返回的期间内，判断，如果在就不是跨期，如果不在就跨期
                if (!isEffectiveDate(format_date_format_yyyy_mm_dd.parse(getCurrentDay()), DateUtils.strToDate((String)((LinkedHashMap) intertermporalDate.getList().get(0)).get("fperiodStart")),
                        DateUtils.strToDate((String) ((LinkedHashMap) intertermporalDate.getList().get(0)).get("fperiodEnd")))) {
                    offlinePolicy.setCrossTerm(IsOrNotEnum.IS.getValue());
                }else{
                    offlinePolicy.setCrossTerm(IsOrNotEnum.NO.getValue());
                }
            }else{
                offlinePolicy.setCrossTerm(IsOrNotEnum.NO.getValue());
            }
        }else{
            offlinePolicy.setCrossTerm(IsOrNotEnum.NO.getValue());
        }
        return offlinePolicy;

    }

    /**
     * 通过产品查询该产品的用户类型是个人还是企业的
     *
     * @param productCode
     * @return
     */
    private String getUserTypeByProductCode(String productCode) {
        List<PolicyAttributeEntity> attrs = policyAttributeService.getAttributes(PolicyAttributeChannelEnum.OFFLINE.getChannel(), null, productCode);
        if (CollectionUtils.isNotEmpty(attrs)) {
            return attrs.get(0).getType();
        }
        return "";
    }

    /**
     * 为线下保单添加 推广营销员相关信息
     *
     * @param offlinePolicy
     * @param offlineOrder
     */
    private void addMarketer(String findCode, OfflinePolicy offlinePolicy, OfflineOrder offlineOrder) {
        OfflineUserTypeEnum userType = OfflineUserTypeEnum.getEnumByType(offlineOrder.getUserType());
        OrgMarketer orgMarketer;

        log.info("{} 为保单：{} 的{}客户，添加推广人。", findCode, userType.getDesc(), offlinePolicy.getPolicyNo());
        //如果是个人用户 添加个人

        if (userType.equals(OfflineUserTypeEnum.INDIVIDUAL)) {
            String userCode = offlinePolicy.getHolderCode();

            ResponseEntity<GenericDataResponse<ManagerInfoVo>> response = registerCustomerService.queryPromotersInfo(findCode, userCode);
            log.info("{} 查询用户推广人配置表结果{}。", findCode, JSON.toJSONString(response));

            if (null != response.getBody() && null != response.getBody().getData()) {
                ManagerInfoVo managerInfoVo = response.getBody().getData();
                log.info("{} 线下保单{}，使用用户配置的推广人{}。", findCode, offlinePolicy.getPolicyNo(), managerInfoVo.getManagerName());
                offlinePolicy.setHolderCode(managerInfoVo.getUserCode());
                offlinePolicy.setMarketerNo(managerInfoVo.getMarketerNo());
                offlinePolicy.setMarketerName(managerInfoVo.getManagerName());
                offlinePolicy.setMarketerUserCode(managerInfoVo.getManagerUserCode());
                offlinePolicy.setMarketerBranchCode(managerInfoVo.getBranchCode());
                offlinePolicy.setMarketerBranchName(managerInfoVo.getBranchName());
                //取大平台的新code
                offlinePolicy.setMarketerChannelCode(MarketerChannelCodeEnum.getNewCodeByCode(managerInfoVo.getChannelCode()));
                offlinePolicy.setMarketerChannelName(managerInfoVo.getChannelName());
                return;
            }

        } else if (userType.equals(OfflineUserTypeEnum.COMPANY)
                && null != (orgMarketer = orgMarketerService.selectByOrgCode(offlinePolicy.getHolderCode()))
                && StringUtils.isNotBlank(orgMarketer.getOrgUserCode())) {

            log.info("{} 查询机构推广人配置表结果{}。", findCode, JSON.toJSONString(orgMarketer));
            //校验该推广人是否离职
            log.info("{} 有机构推广人配置信息，校验该推广人：{}是否离职。", findCode, orgMarketer.getMarketerName());
            RegisterCustomer registerCustomer = new RegisterCustomer();
            registerCustomer.setUserCode(orgMarketer.getMarketerUserCode());
            ResponseEntity<GenericDataResponse<RegisterCustomer>> checkValue = registerCustomerService.checkValidity(findCode, registerCustomer);

            //推广人有效 实时查询营销员表
            if (GenericDataResponse.CODE_OK.equals(checkValue.getBody().getCode())) {
                MarketerInfoQO marketerInfoQO = new MarketerInfoQO();
                marketerInfoQO.setMarketerNo(orgMarketer.getMarketerNo());
                List<MarketerInfoEntity> marketerInfoEntities = marketerInfoService.queryMarketerList(findCode, marketerInfoQO, false);
                if (marketerInfoEntities.size() > 0) {
                    log.info("{} 线下保单{}，使用机构配置的推广人{}。", findCode, offlinePolicy.getPolicyNo(), orgMarketer.getMarketerName());
                    MarketerInfoEntity marketerInfoEntity = marketerInfoEntities.get(0);
                    offlinePolicy.setHolderCode(orgMarketer.getOrgUserCode());
                    offlinePolicy.setMarketerNo(orgMarketer.getMarketerNo());
                    offlinePolicy.setMarketerName(orgMarketer.getMarketerName());
                    offlinePolicy.setMarketerUserCode(orgMarketer.getMarketerUserCode());
                    offlinePolicy.setMarketerBranchCode(marketerInfoEntity.getBranchCode());
                    offlinePolicy.setMarketerBranchName(marketerInfoEntity.getBranchName());
                    //取大平台的新code
                    offlinePolicy.setMarketerChannelCode(MarketerChannelCodeEnum.getNewCodeByCode(marketerInfoEntity.getChannelCode()));
                    offlinePolicy.setMarketerChannelName(marketerInfoEntity.getChannelName());
                }
                return;
            }
        }
        log.info("{} 线下保单{}，使用订单选择的推广人{}。", findCode, offlinePolicy.getPolicyNo(), offlineOrder.getMarketerName());
        offlinePolicy.setMarketerNo(offlineOrder.getMarketerNo());
        offlinePolicy.setMarketerName(offlineOrder.getMarketerName());
        offlinePolicy.setMarketerUserCode(offlineOrder.getMarketerUserCode());
        offlinePolicy.setMarketerBranchCode(offlineOrder.getBranchCode());
        offlinePolicy.setMarketerBranchName(offlineOrder.getBranchName());
        offlinePolicy.setMarketerChannelCode(MarketerChannelCodeEnum.getNewCodeByCode(offlineOrder.getMarketerChannelCode()));
        offlinePolicy.setMarketerChannelName(offlineOrder.getMarketerChannelName());
    }

    /**
     * 调用业管获取跨期区间
     * @param insureDate
     * @return
     * @throws Exception
     */
    public GenericListResponse getIntertemporal(Date insureDate) throws Exception {
        String fperiod = DateUtils.converDateYm(insureDate);
        log.info("格式化调用业管跨期的参数为"+fperiod);
        GenericListResponse intertermporalDate = bmsClient.getIntertemporal(fperiod);
        return intertermporalDate;
    }

    /**
     * 通过文件id 得到保单录入 数据
     *
     * @param policyFiles
     * @return
     * @throws Exception
     */
    private List<OfflinePolicy> getOfflinePolicyByFiles(String findCode, List<FileVO> policyFiles) throws Exception {
        log.info("{} 通过文件id 集合，录入保单数据,{}", findCode, JSON.toJSONString(policyFiles));

        List<OfflinePolicy> offlinePolicies = Lists.newArrayList();
        for (FileVO fileVO : policyFiles) {
            List<ExcelFileDetailVo> excelFileDetailVos;
            try {
                ResponseEntity<GenericListResponse<ExcelFileDetailVo>> responseEntity =
                        parserClient.excelDetailList(fileVO.getFileId(), null, 1, Integer.MAX_VALUE);
                excelFileDetailVos = responseEntity.getBody().getList();
            } catch (Exception e) {
                log.error("调用清单出错，入参:{}", fileVO.getFileId());
                throw new RuntimeException("清单服务异常，请稍后重试!");
            }
            if (CollectionUtils.isEmpty(excelFileDetailVos)) {
                log.error("清单查询无数据，入参:{}", fileVO.getFileId());
                throw new RuntimeException("清单查询无结果，请联系管理人员!");
            }
            for (ExcelFileDetailVo excelFileDetailVo : excelFileDetailVos) {
                OfflinePolicy offlinePolicy;
                try {
                    offlinePolicy = JSON.parseObject(excelFileDetailVo.getContent(), OfflinePolicy.class);
                    offlinePolicy.setFileId(fileVO.getFileId());
                } catch (Exception e) {
                    log.error("清单查询数据格式不正确，入参:{}", excelFileDetailVo.getContent());
                    throw new RuntimeException("清单数据异常，请联系管理人员!");
                }
                offlinePolicies.add(offlinePolicy);
            }
        }
        return offlinePolicies;
    }

    @Override
    public ResponseEntity<GenericListResponse<OfflineOrderVo>> queryOfflinePolicy(OfflinePolicyQO offlinePolicyQO){
        Long count = offlineMapper.queryOfflinePolicyCount(offlinePolicyQO);
        if (null == count || count <= 0) {
            return GenericListResponse.listNoCount(null);
        }
        List<OfflineOrderVo> offlineOrderVos = offlineMapper.queryOfflinePolicy(offlinePolicyQO);
        return GenericListResponse.listAndCount(offlineOrderVos, count);
    }

    /**
     * 校验上传保单文件是否存在倒签以及跨期
     *
     * @param findCode
     * @param policyFile
     * @return
     * @throws Exception
     */
    @Override
    public ResponseEntity checkFileIntertemporal(String findCode, String policyFile) throws Exception {
        JSONObject jsonObj = new JSONObject(policyFile);
        policyFile = jsonObj.getString("policyFile");
        //解析清单数据
        List<FileVO> policyFiles;
        try {
            policyFiles = JSON.parseArray(policyFile, FileVO.class);
        } catch (Exception e) {
            log.info("{} 保单文件json格式不正确,{}", findCode, policyFile);
            return GenericDataResponse.errorWithMsg("保单文件json格式不正确!");
        }
        //通过文件id集合得到对应清单解析的结果数据集
        List<OfflinePolicy> offlinePolicies = getOfflinePolicyByFiles(findCode, policyFiles);
        //定义跨期和倒签的map
        Map<String, String> map = new HashMap<>();
        map.put("isBackdating", "false"); //是否倒签
        map.put("isInIntertemporal", "false"); //是否跨期
        for (OfflinePolicy offlinePolicy : offlinePolicies) {
            //判断保单签单日期是否晚于保险起期,循环只要有一个晚于，则跳出
            Date startDate = offlinePolicy.getStartDate();
            Date insureDate = offlinePolicy.getInsureDate();
            if (insureDate.after(startDate)) {
                //自動覆蓋
                map.put("isBackdating", "true"); //签单日期是否晚于
                break;
            }
        }
        for (OfflinePolicy offlinePolicy : offlinePolicies) {
            //判断当前日期和签单日期是否在同一月份,不同月份跨期,调用业管
            if (!DateUtils.isSameMonth(new Date(), offlinePolicy.getInsureDate())) {
                //根据签单日期查询跨期 从业管里面获取跨期起期和止期  签单日期需要格式化成类似 ：202103
                GenericListResponse intertermporalDate = getIntertemporal(offlinePolicy.getInsureDate());
                if (intertermporalDate.getList()!=null) {
                    //拿当前时间也就是录单时间，在业管返回的期间内，判断，如果在就不是跨期，如果不在就跨期
                    if (!isEffectiveDate(format_date_format_yyyy_mm_dd.parse(getCurrentDay()), DateUtils.strToDate((String) ((LinkedHashMap) intertermporalDate.getList().get(0)).get("fperiodStart")),
                            DateUtils.strToDate((String) ((LinkedHashMap) intertermporalDate.getList().get(0)).get("fperiodEnd")))) {
                        //自動覆蓋
                        map.put("isInIntertemporal", "true"); //签单日期是否在会计区间
                        break;
                    }
                } else {
                    log.info("未获取到业管跨期区间");
                }
            }
        }
        return GenericDataResponse.okWithData(map);
    }

    @Override
    public ResponseEntity reclaim(List<Map<String, String>> operparam) throws Exception {
        OfflinePolicy offlinePolicy = new OfflinePolicy();
        Weekend<OfflinePolicy> updWeekend = Weekend.of(OfflinePolicy.class);
        WeekendCriteria<OfflinePolicy,Object> updCriteria = updWeekend.weekendCriteria();
        int n = 0; //多条sql执行数量
        //调用业管认领查询接口
        Map<String,Object> mhdsDitchList = sttlManClient.mhdsDitchSelectByPolicyNo(operparam.get(0).get("policyno"),
                operparam.get(0).get("orgcode"),
                "7");
        log.info("业管认领查询返回数据",JsonUtils.toJson(mhdsDitchList));
        //未查询到
        if(!mhdsDitchList.get("code").equals("0000")){
            //修改保单号状态为无认领信息
            offlinePolicy.setClaimStatus(ClaimStatusEnum.DEFAULT.getCode());
            offlinePolicy.setClaimReason((String) mhdsDitchList.get("msg"));
            offlinePolicyMapper.updateByPrimaryKeySelective(offlinePolicy);
        }else{
            //调用业管认领接口
            Map<String,Object> stringStringMap = sttlManClient.mhdsDitchClaim(operparam);
            log.info("业管认领接口返回数据",JsonUtils.toJson(stringStringMap));
            for (int i = 0; i < operparam.size(); i++) {
                String policyno = operparam.get(i).get("policyno");
                updCriteria.andEqualTo(OfflinePolicy::getPolicyNo,policyno);
                if(stringStringMap.get("executecode").equals("0")){
                    //认领成功，修改状态
                    offlinePolicy.setClaimStatus(ClaimStatusEnum.SUCCESS.getCode());
                    offlinePolicy.setClaimReason(null);
                }else{
                    //认领失败
                    offlinePolicy.setClaimStatus(ClaimStatusEnum.ERROR.getCode());
                    offlinePolicy.setClaimReason((String) stringStringMap.get("executenote"));
                }
                n = offlinePolicyMapper.updateByExampleSelective(offlinePolicy, updWeekend);
            }
        }
         if (n > 0) {
            return GenericDataResponse.ok();
        }
        return GenericDataResponse.errorWithMsg("业管认领接口失败!");
    }

    public static void main(String[] args) throws ParseException {
            SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        String ens="2021-03-17";
        String snc="2021-03-18";
        System.out.println(fmt.parse(ens));
        System.out.println(fmt.parse(snc));
        System.out.println(new Date());
        System.out.println(getCurrentDay());
        System.out.println(DateUtils.converDateYm(new Date()));
        //fmt.setTimeZone(new TimeZone()); // 如果需要设置时间区域，可以在这里设置
        System.out.println(isEffectiveDate(format_date_format_yyyy_mm_dd.parse(getCurrentDay()), fmt.parse(ens),fmt.parse(snc)));
        String policyFile="{\"policyFile\":[{\"name\":\"线下保单录入清单模板1.xlsx\",\"fileName\":\"线下保单录入清单模板1.xlsx\",\"fileId\":\"2488409785363073695\",\"num\":3,\"fileType\":\"F001\",\"createdTime\":\"2021-03-22 15:11:27\",\"fileUrl\":\"\",\"uid\":1616397087307,\"status\":\"success\"}]}";
        JSONObject jsonObj = new JSONObject(policyFile);
        String abc =jsonObj.getString("policyFile");
        System.out.println(abc);
        //解析清单数据
        List<FileVO> policyFiles;
        policyFiles = JSON.parseArray(abc, FileVO.class);
        System.out.println(policyFiles);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        Date birthday = sdf.parse("1988-08-13 13:13:13");
        System.out.println("birthday = " + birthday.toString());
        System.out.println("birthday = " + birthday.getTime());

        String abcd = "[{\"businessTypeCode\":\"F002\",\"fileId\":\"2488411056673393343\",\"fileName\":\"我学保济.xlsx\",\"createdTime\":\"2021-03-24 12:12:19\",\"name\":\"我学保济.xlsx\",\"uid\":1616559139934,\"status\":\"success\"},{\"businessTypeCode\":\"F002\",\"fileId\":\"2488411056673393344\",\"fileName\":\"我学保济宁学平险批量投保模板 (1).xlsx\",\"createdTime\":\"2021-03-24 12:12:20\",\"name\":\"我学保济宁学平险批量投保模板 (1).xlsx\",\"uid\":1616559140220,\"status\":\"success\"}]";
        List<FileVO> policyFilesd;
        StringBuilder stringBuilder = new StringBuilder();
        policyFilesd = JSON.parseArray(abcd, FileVO.class);
        for (int i = 0; i < policyFilesd.size(); i++) {
            if(i<policyFilesd.size()-1){
                stringBuilder.append(policyFilesd.get(i).getFileId()).append(",");
            }else{
                stringBuilder.append(policyFilesd.get(i).getFileId());
            }
            //判断到末尾不需要加符号

        }
        System.out.println(stringBuilder);


        SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdfd.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        Date birthdays = sdfd.parse("1988-08-13 13:13:13");
        System.out.println("birthday = " + birthdays.toString());
        System.out.println("birthday = " + birthdays.getTime());

    }
    @Override
    public ResponseEntity<GenericDataResponse<OfflineOrderBO>> queryOfflineOrderDetails(Long orderId) {
        //查询线下定单
        OfflineOrder offlineOrder = offlineOrderMapper.selectByPrimaryKey(orderId);
        if (null == offlineOrder) {
            return GenericDataResponse.errorWithMsg("无查询结果!", OfflineOrderBO.class);
        }
        //查询线下保单
        OfflinePolicy offlinePolicy = new OfflinePolicy();
        offlinePolicy.setOrderId(orderId);
        List<OfflinePolicy> policies = offlinePolicyMapper.select(offlinePolicy);

        return GenericDataResponse.okWithData(new OfflineOrderBO(offlineOrder, policies));
    }

    @Override
    @Transactional
    public ResponseEntity updateOfflineOrder(String findCode, OfflineOrderInputDTO offlineOrderInputDTO) throws Exception {
        OfflineOrder oldOfflineOrder = offlineOrderMapper.selectByPrimaryKey(offlineOrderInputDTO.getId());
        //如果没有结果集，或该记录已经被删除
        if (null == oldOfflineOrder || IsOrNotEnum.is(oldOfflineOrder.getIsDeleted())) {
            return GenericDataResponse.errorWithMsg("不正确的定单ID");
        }

        //如果产品编码不一致需要获得新的用户类型
        if (!oldOfflineOrder.getProductCode().equals(offlineOrderInputDTO.getProductCode())) {
            String userType = getUserTypeByProductCode(offlineOrderInputDTO.getProductCode());
            if (StringUtils.isBlank(userType)) {
                log.info("{} 该产品:{}({})没有配置用户类型信息", findCode, offlineOrderInputDTO.getProductName(), offlineOrderInputDTO.getProductCode());
                return GenericDataResponse.errorWithMsg("该产品没有配置用户类型信息, 请联系管理人员!");
            }
            log.info("{} 该产品:{}({})配置用户类型为{}", findCode, offlineOrderInputDTO.getProductName(), offlineOrderInputDTO.getProductCode(), userType);

            offlineOrderInputDTO.setUserType(userType);
        }

        OfflineOrder offlineOrder = offlineOrderInputDTO.changeToOfflineOrder();
        offlineOrder.setUpdateTime(new Date());
        //录入时间：修改线下录入，录入时间取当前时间
        offlineOrder.setInputTime(new Date());
        offlineOrderMapper.updateByPrimaryKeySelective(offlineOrder);

        //查看是否修改保单的清单, 如果需要直接处理
        updatePolicy(findCode, oldOfflineOrder.getPolicyFile(), offlineOrder.getPolicyFile(), offlineOrderInputDTO);

        //如果新旧推广人不一致，更新保单表中所有原推广人为订单上推广人的记录
        if (!Objects.equals(offlineOrderInputDTO.getMarketerUserCode(), oldOfflineOrder.getMarketerUserCode())) {
            updatePolicyMarketer(oldOfflineOrder, offlineOrderInputDTO);
        }
        return GenericDataResponse.ok();
    }

    /**
     * 更新推广营销人
     *
     * @param oldOfflineOrder
     * @param offlineOrderInputDTO
     */
    private void updatePolicyMarketer(OfflineOrder oldOfflineOrder, OfflineOrderInputDTO offlineOrderInputDTO) {
        Weekend<OfflinePolicy> updWeekend = Weekend.of(OfflinePolicy.class);
        WeekendCriteria<OfflinePolicy, Object> updCriteria = updWeekend.weekendCriteria();
        updCriteria.andEqualTo(OfflinePolicy::getOrderId, oldOfflineOrder.getId());
        if (StringUtils.isNotBlank(oldOfflineOrder.getMarketerUserCode())) {
            updCriteria.andEqualTo(OfflinePolicy::getMarketerUserCode, oldOfflineOrder.getMarketerUserCode());
        }
        updCriteria.andEqualTo(OfflinePolicy::getIsDeleted, IsOrNotEnum.NO.getValue());

        List<OfflinePolicy> offlinePolicies = offlinePolicyMapper.selectByExample(updWeekend);
        for (OfflinePolicy offlinePolicy : offlinePolicies) {
            offlinePolicy.setMarketerUserCode(offlineOrderInputDTO.getMarketerUserCode());
            offlinePolicy.setMarketerName(offlineOrderInputDTO.getMarketerName());
            offlinePolicy.setMarketerNo(offlineOrderInputDTO.getMarketerNo());
            offlinePolicy.setMarketerBranchCode(offlineOrderInputDTO.getMarketerBranchCode());
            offlinePolicy.setMarketerBranchName(offlineOrderInputDTO.getMarketerBranchName());
            offlinePolicy.setMarketerChannelCode(MarketerChannelCodeEnum.getNewCodeByCode(offlineOrderInputDTO.getMarketerChannelCode()));
            offlinePolicy.setMarketerChannelName(offlineOrderInputDTO.getMarketerChannelName());
            //这一块必须用updateByPrimaryKey 因为有可能是删除营销员信息
            offlinePolicyMapper.updateByPrimaryKey(offlinePolicy);
        }

    }

    /**
     * 通过线下录单文件的文件json 做修改操作
     * @param oldPolicyFile
     * @param newPolicyFile
     * @param offlineOrderInputDTO
     * @throws Exception
     */
    private void updatePolicy(String findCode, String oldPolicyFile, String newPolicyFile, OfflineOrderInputDTO offlineOrderInputDTO) throws Exception{
        //如果两个文件json相同不处理
        if(oldPolicyFile.equals(newPolicyFile)){
            log.info("{} 清单文件json相同", findCode);
            //根据orderId查询policy所有的记录
            OfflinePolicy offlinePolicy = new OfflinePolicy();
            offlinePolicy.setOrderId(offlineOrderInputDTO.getId());
            offlinePolicy.setIsDeleted(IsDeletedEnum.NO.getValue());
            List<OfflinePolicy> offlinePolicyList = offlinePolicyMapper.select(offlinePolicy);
            //再次判断是否跨期
            for (OfflinePolicy oldofflinePolicy : offlinePolicyList){
                    Date startDate = oldofflinePolicy.getStartDate();
                    Date issueDate = oldofflinePolicy.getInsureDate();
                    checkBacklogAsCrossTerm(oldofflinePolicy,issueDate,startDate);
                    offlinePolicyMapper.updateByPrimaryKeySelective(oldofflinePolicy);
             }
            return;
        }
        //旧线下录单文件
        List<FileVO> oldPolicyFiles;
        try{
            oldPolicyFiles = JSON.parseArray(oldPolicyFile, FileVO.class);
        } catch (Exception e){
            log.info("{} 原线下定单的, 保单文件json格式不正确: {}", findCode, oldPolicyFile);
            throw new RuntimeException("原线下定单的, 保单文件json格式不正确!");
        }
        //新上传的线下录单文件
        List<FileVO> newPolicyFiles;
        try{
            newPolicyFiles = JSON.parseArray(newPolicyFile, FileVO.class);
        } catch (Exception e){
            log.info("{} 保单文件json格式不正确: {}", findCode, newPolicyFile);
            throw new RuntimeException("保单文件json格式不正确!");
        }
        if(CollectionUtils.isEmpty(newPolicyFiles)){
            log.info("{} 保单文件不能为空!", findCode);
            throw new RuntimeException("保单文件不能为空!");
        }
        log.info("{} 判断旧文件是否都在新文件当中，如果不在需要删除对应的保单信息!", findCode);
        //判断旧文件是否都在新文件当中  如果不在需要删除对应的保单信息
        for(FileVO oldFileVO : oldPolicyFiles){
            boolean isHas = false;
            for(FileVO newFileVO : newPolicyFiles){
                //如果文件相同
                if(oldFileVO.getFileId().equals(newFileVO.getFileId())){
                    isHas = true;
                    break;
                }
            }
            if(!isHas){
                //删除
                OfflinePolicy offlinePolicy = new OfflinePolicy();
                offlinePolicy.setIsDeleted(IsDeletedEnum.IS.getValue());

                Weekend<OfflinePolicy> updWeekend = Weekend.of(OfflinePolicy.class);
                WeekendCriteria<OfflinePolicy,Object> updCriteria = updWeekend.weekendCriteria();
                updCriteria.andEqualTo(OfflinePolicy::getFileId, oldFileVO.getFileId());
                offlinePolicyMapper.updateByExampleSelective(offlinePolicy, updWeekend);
            }
        }
        //判断新文件是否都在旧文件当中  如果不在需要插入对应的保单信息
        List<FileVO> insertList = Lists.newArrayList();
        for(FileVO newFileVO : newPolicyFiles){
            boolean isHas = false;
            for(FileVO oldFileVO : oldPolicyFiles){
                //如果文件相同
                if(newFileVO.getFileId().equals(oldFileVO.getFileId())){
                    isHas = true;
                    break;
                }
            }
            //如果不存在就是需要添加的
            if(!isHas){
                //添加到插入列表
                insertList.add(newFileVO);
            }
        }
        log.info("{} 最终需要插入的文件列表!{}", findCode, JSON.toJSONString(insertList));
        //得到文件对应的保单列表
        List<OfflinePolicy> offlinePolicies = getOfflinePolicyByFiles(findCode, insertList);
        log.info("{} 需要插入的保单集合!{}", findCode, JSON.toJSONString(offlinePolicies));
        for(OfflinePolicy offlinePolicy : offlinePolicies){
            //为线下保单添加 推广营销员相关信息
            //  addMarketer(findCode, offlinePolicy, offlineOrderInputDTO);
            //插入的时候判断是否倒签以及跨期
            Date startDate = offlinePolicy.getStartDate();
            Date issueDate = offlinePolicy.getInsureDate();
            checkBacklogAsCrossTerm(offlinePolicy,issueDate,startDate);
            offlinePolicy.setOrderId(offlineOrderInputDTO.getId());
            offlinePolicyMapper.insertSelective(offlinePolicy);
        }

    }

    /**
     * 得到用户的 userCode
     *
     * @param offlineOrder
     * @param offlinePolicy
     * @return
     */
    private String getHolderCode(OfflineOrder offlineOrder, OfflinePolicy offlinePolicy) throws Exception {
        if (OfflineUserTypeEnum.COMPANY.getType().equals(offlineOrder.getUserType())) {
            return getCompanyHolderCode(offlineOrder, offlinePolicy);
        } else {
            return getIndividualHolderCode(offlineOrder, offlinePolicy, true);
        }
    }

    /**
     * 得到个人的用户code
     *
     * @param offlineOrder
     * @param offlinePolicy
     * @param doRegist      如果用户不存在是否注册true 注册 默认false
     * @return
     */
    private String getIndividualHolderCode(OfflineOrder offlineOrder, OfflinePolicy offlinePolicy, boolean doRegist) throws Exception {
        //支持个人如果有手机号就添加手机号否则加入区县代码
        //查询是否生成过用户信息
        Weekend<OfflineUser> weekend = Weekend.of(OfflineUser.class);
        WeekendCriteria<OfflineUser, Object> criteria = weekend.weekendCriteria();
        criteria.andEqualTo(OfflineUser::getIsDeleted, IsOrNotEnum.NO.getValue());
        criteria.andEqualTo(OfflineUser::getUserType, offlineOrder.getUserType());
        //校验投保人手机号是否存在
        if (StringUtils.isNotBlank(offlinePolicy.getHolderPhone())) {
            criteria.andEqualTo(OfflineUser::getUserPhone, offlinePolicy.getHolderPhone());
            List<OfflineUser> offlineUsers = offlineUserMapper.selectByExample(weekend);
            if (CollectionUtils.isNotEmpty(offlineUsers)) {
                return offlineUsers.get(0).getUserCode();
            }
        }
        //最后校验地区及姓名 如果订单上有区就用区如果没有区编码就用市编码
        if (StringUtils.isNotBlank(offlineOrder.getCountyCode())) {
            criteria.andEqualTo(OfflineUser::getCountyCode, offlineOrder.getCountyCode());
        } else {
            criteria.andEqualTo(OfflineUser::getCityCode, offlineOrder.getCityCode());
        }

        criteria.andEqualTo(OfflineUser::getUserName, offlinePolicy.getHolderName());
        List<OfflineUser> offlineUsers = offlineUserMapper.selectByExample(weekend);
        if (CollectionUtils.isNotEmpty(offlineUsers)) {
            return offlineUsers.get(0).getUserCode();
        }
        if (doRegist) {
            String userAccount = StringUtils.isBlank(offlinePolicy.getHolderPhone()) ? attrConfigService.createOfflineUserCode() : offlinePolicy.getHolderPhone();
            //通过手机号注册，如果手机号为空 自成生成编码
            String userCode = weChatAppLoginService.getUserCode(userAccount);
            offlinePolicy.setHolderCode(userCode);
            //插入到线下用户表
            insertOfflineUserByPolicy(offlineOrder, offlinePolicy, userAccount);
            return userCode;
        }

        return "";
    }

    /**
     * 插入
     *
     * @param offlinePolicy
     * @return
     */
    private void insertOfflineUserByPolicy(OfflineOrder offlineOrder, OfflinePolicy offlinePolicy, String userAccount) {
        OfflineUser offlineUser = new OfflineUser();
        offlineUser.setUserName(offlinePolicy.getHolderName());
        offlineUser.setUserCode(offlinePolicy.getHolderCode());
        offlineUser.setUserAccount(userAccount);
        offlineUser.setUserPhone(offlinePolicy.getHolderPhone());
        offlineUser.setUserType(offlineOrder.getUserType());
        offlineUser.setCityCode(offlineOrder.getCityCode());
        offlineUser.setCountyCode(offlineOrder.getCountyCode());
        offlineUser.setCreateTime(new Date());
        offlineUser.setIsDeleted(IsOrNotEnum.NO.getValue());
        offlineUserMapper.insertSelective(offlineUser);
    }


    /**
     * 得到企业的用户code
     *
     * @param offlineOrder
     * @param offlinePolicy
     * @return
     */
    private String getCompanyHolderCode(OfflineOrder offlineOrder, OfflinePolicy offlinePolicy) {
        //查询是否生成过用户信息
        Weekend<OfflineUser> weekend = Weekend.of(OfflineUser.class);
        WeekendCriteria<OfflineUser, Object> criteria = weekend.weekendCriteria();
        criteria.andEqualTo(OfflineUser::getUserName, offlinePolicy.getHolderName());
        criteria.andEqualTo(OfflineUser::getUserType, offlineOrder.getUserType());
        criteria.andEqualTo(OfflineUser::getIsDeleted, IsOrNotEnum.NO.getValue());
        List<OfflineUser> offlineUsers = offlineUserMapper.selectByExample(weekend);
        String holderCode;
        if (CollectionUtils.isNotEmpty(offlineUsers)) {
            return offlineUsers.get(0).getUserCode();
        } else {
            String holderName = offlinePolicy.getHolderName();
            //注册
            OfflineRegisterDTO offlineRegisterDTO = new OfflineRegisterDTO();
            offlineRegisterDTO.setLinkManName(offlineOrder.getOperatorName());
            offlineRegisterDTO.setLinkManPhone(offlineOrder.getOperatorPhone());
            offlineRegisterDTO.setOrgAddress(offlineOrder.getCityName());
            offlineRegisterDTO.setOrgFullName(holderName);
            if (StringUtils.isNotBlank(offlineOrder.getCountyCode())) {
                offlineRegisterDTO.setProvinceCode(offlineOrder.getCountyCode());
            } else {
                offlineRegisterDTO.setProvinceCode(offlineOrder.getCityCode());
            }
            try {
                GenericListResponse<OfflineRegisterVo> ret = userClient.medRecordOrgRegister(Lists.newArrayList(offlineRegisterDTO));
                //默认成功 如果不成功走异常回滚
                holderCode = ret.getList().get(0).getUserCode();
                offlinePolicy.setHolderCode(holderCode);
                //企业认证的登录名由用户中心生成
                insertOfflineUserByPolicy(offlineOrder, offlinePolicy, ret.getList().get(0).getOrgCode());
            } catch (Exception e) {
                //如果不能取到 就表示注册失败
                log.error("用户名为：{},的用户注册失败!入参：{}", holderName, JSON.toJSONString(offlineRegisterDTO), e);
                throw new RuntimeException(holderName + "用户注册失败!", e);
            }
        }
        return holderCode;
    }

    /**
     * 线下保单录入审核功能
     * @param findCode
     * @param offlineOrder
     * @return
     * @throws Exception
     */
    @Override
    public ResponseEntity auditOfflineOrder(String findCode, OfflineOrder offlineOrder) throws Exception {
        OfflineOrder newOfflineOrder = new OfflineOrder();
        newOfflineOrder.setAuditTime(new Date());
        newOfflineOrder.setUpdateTime(new Date());
        newOfflineOrder.setId(offlineOrder.getId());
        newOfflineOrder.setAuditStatus(offlineOrder.getAuditStatus());
        newOfflineOrder.setAuditOpinion(offlineOrder.getAuditOpinion());
        //如果是审核通过  需要做线下推送到投保中心
        if (AuditStatusEnum.SUCCESS.getCode().equals(offlineOrder.getAuditStatus())) {
            OfflineOrder pushOrder = offlineOrderMapper.selectByPrimaryKey(offlineOrder.getId());
            if (pushOrder.getAuditStatus().equals(AuditStatusEnum.SUCCESS.getCode())) {
                return GenericDataResponse.errorWithMsg("已经为审核通过状态，不需要再次审核!");
            }
            pushPolicyToIns(findCode, pushOrder);
        }
        offlineOrderMapper.updateByPrimaryKeySelective(newOfflineOrder);
        return GenericDataResponse.ok();
    }

    @Override
    public OfflineOrderVo queryByPolicyNo(String policyNo) {
        OfflineOrderVo offlineOrderVo = null;
        //查询关联的线下录入的保单
        if (StringUtils.isNotBlank(policyNo)) {
            OfflinePolicyQO offlinePolicyQO = new OfflinePolicyQO();
            offlinePolicyQO.setPolicyNo(policyNo);
            List<OfflineOrderVo> offlineOrderVos = offlineMapper.queryOfflinePolicy(offlinePolicyQO);
            if (CollectionUtils.isNotEmpty(offlineOrderVos)) {
                //取出结果集中的第一条保单信息
                offlineOrderVo = offlineOrderVos.get(0);
            }
        }
        return offlineOrderVo;
    }

    @Override
    public void pushPolicyToIns(String findCode, Long id) throws Exception {
        OfflineOrder offlineOrder = offlineOrderMapper.selectByPrimaryKey(id);
        if (null == offlineOrder) {
            throw new Exception("定单id不存在!");
        }
        if (!offlineOrder.getAuditStatus().equals(AuditStatusEnum.SUCCESS.getCode())) {
            throw new Exception("定单非审核通过状态，不能推送!");
        }
        pushPolicyToIns(findCode, offlineOrder);
    }

    @Override
    public ResponseEntity<GenericListResponse<OfflineOrder>> queryOfflineOrder(OfflineOrderQO offlineOrderQO) {
        Long count = offlineMapper.queryOfflineOrderCount(offlineOrderQO);
        if (null == count || count <= 0) {
            return GenericListResponse.listNoCount(null);
        }
        List<OfflineOrder> offlineOrderVos = offlineMapper.queryOfflineOrder(offlineOrderQO);
        return GenericListResponse.listAndCount(offlineOrderVos, count);
    }

    @Override
    public List<String> checkPolicyNos(List<String> policyNos) {
        Weekend<OfflinePolicy> weekend = new Weekend<>(OfflinePolicy.class);
        WeekendCriteria<OfflinePolicy, Object> criteria = weekend.weekendCriteria();
        criteria.andNotEqualTo(OfflinePolicy::getPushStatus, PushStatusEnum.ERROR.getCode());
        criteria.andIn(OfflinePolicy::getPolicyNo, policyNos);
        criteria.andEqualTo(OfflinePolicy::getIsDeleted, IsDeletedEnum.NO.getValue());
        List<OfflinePolicy> offlinePolicies = offlinePolicyMapper.selectByExample(weekend);
        //转换LIST 去重复
        return Lists.transform(offlinePolicies, offlinePolicy -> offlinePolicy.getPolicyNo()).stream().distinct().collect(Collectors.toList());
    }

    @Override
    public ResponseEntity deleteOrder(Long orderId) {
        OfflineOrder offlineOrder = offlineOrderMapper.selectByPrimaryKey(orderId);
        if (null == offlineOrder || IsDeletedEnum.is(offlineOrder.getIsDeleted())) {
            return GenericDataResponse.errorWithMsg("订单申请不存在!");
        }
        if (!AuditStatusEnum.BACK.getCode().equals(offlineOrder.getAuditStatus())) {
            return GenericDataResponse.errorWithMsg("订单申请非回退状态不能删除!");
        }

        int n = 0;
        //删除保单信息
        Weekend<OfflinePolicy> weekend = new Weekend<>(OfflinePolicy.class);
        WeekendCriteria<OfflinePolicy, Object> criteria = weekend.weekendCriteria();
        criteria.andEqualTo(OfflinePolicy::getOrderId, orderId);

        OfflinePolicy offlinePolicy = new OfflinePolicy();
        offlinePolicy.setIsDeleted(IsDeletedEnum.IS.getValue());
        n += offlinePolicyMapper.updateByExampleSelective(offlinePolicy, weekend);

        //删除订单信息
        OfflineOrder updateOrder = new OfflineOrder();
        updateOrder.setId(orderId);
        updateOrder.setIsDeleted(IsDeletedEnum.IS.getValue());
        n += offlineOrderMapper.updateByPrimaryKeySelective(updateOrder);

        if (n > 0) {
            return GenericDataResponse.ok();
        }
        return GenericDataResponse.errorWithMsg("订单申请删除失败!");
    }

    @Override
    @Transactional
    public ResponseEntity savePolicyDetailFile(String findCode, SavePolicyDetailFileQo savePolicyDetailFileQo) throws Exception {
        log.info("{} 上传线下录入人员清单入参: {}", findCode, JSON.toJSONString(savePolicyDetailFileQo));
        if (null == savePolicyDetailFileQo || StringUtils.isBlank(savePolicyDetailFileQo.getPolicyNo())) {
            log.info("{} 保单号不能为空", findCode);
            return GenericDataResponse.errorWithMsg("保单号不能为空!");
        }
        if (StringUtils.isBlank(savePolicyDetailFileQo.getDetailFileId())) {
            return GenericDataResponse.errorWithMsg("人员清单id不能为空!");
        }

        //查询该保单的订单信息
        OfflinePolicyQO offlinePolicyQO = new OfflinePolicyQO();
        offlinePolicyQO.setPolicyNo(savePolicyDetailFileQo.getPolicyNo());
        offlinePolicyQO.setPushStatus(PushStatusEnum.SUCCESS.getCode());
        List<OfflineOrderVo> offlineOrderVos = offlineMapper.queryOfflinePolicy(offlinePolicyQO);
        if (CollectionUtils.isEmpty(offlineOrderVos)) {
            log.info("{} 该保单状态异常", findCode);
            return GenericDataResponse.errorWithMsg("该保单状态异常!");
        }
        OfflineOrderVo offlineOrderVo = offlineOrderVos.get(0);
        log.info("{} 线下录入的订单查询出参:{}", findCode, JSON.toJSONString(offlineOrderVos));
        if (savePolicyDetailFileQo.getDetailFileId().equals(offlineOrderVo.getDetailFileId())) {
            log.info("{} 人员清单无变更", findCode);
            return GenericDataResponse.errorWithMsg("人员清单无变更!");
        }
        if (!offlineOrderVo.getPushStatus().equals(PushStatusEnum.SUCCESS.getCode())) {
            log.info("{} 该保单推送状态未成功不能添加人员清单", findCode);
            return GenericDataResponse.errorWithMsg("该保单推送状态未成功不能添加人员清单!");
        }
        if (StringUtils.isBlank(offlineOrderVo.getAppCode())) {
            log.info("{} 该保单的投保单号为空，请联系管理人员。", findCode);
            return GenericDataResponse.errorWithMsg("该保单的投保单号为空，请联系管理人员。");
        }
        //人员清单入库
        endorseService.updateAppEndorseByFileId(findCode, offlineOrderVo.getAppCode(), savePolicyDetailFileQo.getDetailFileId(), savePolicyDetailFileQo.getUserCode());
        //关联/删除/修改 人员清单
        offlineMapper.updatePolicyDetailFile(savePolicyDetailFileQo);

        return GenericDataResponse.ok();
    }

    @Override
    public ResponseEntity selectPolicyDetailFile(String policyNo) {
        OfflinePolicy offlinePolicy = new OfflinePolicy();
        offlinePolicy.setPolicyNo(policyNo);
        offlinePolicy.setIsDeleted(IsDeletedEnum.NO.getValue());

        OfflinePolicy offlinePolicy2 = offlinePolicyMapper.selectOne(offlinePolicy);
        log.info("通过保单号{}查询清单文件结果：{}", policyNo, JSON.toJSONString(offlinePolicy2));
        if (offlinePolicy2 == null) {
            //无保单信息
            return GenericDataResponse.okWithData("");
        }
        String detailFileId = offlinePolicy2.getDetailFileId();
        if (StringUtils.isNotBlank(detailFileId)) {
            detailFileId = MyStringUtils.createFileUrl("edu-svc", BusinessTypeCodeEnum.L001.getCode(), String.valueOf(offlinePolicy2.getId()), "0", detailFileId);
        } else {
            detailFileId = "";
        }
        return GenericDataResponse.okWithData(detailFileId);
    }

    @Override
    public ResponseEntity<GenericListResponse<OfflineProductDTO>> offlineProductList(String findCode, String userCode) {
        log.info("{}通过用户查询线下录入的产品列表，userCode:{}", findCode, userCode);
        List<OfflineProductDTO> retList = Lists.newArrayList();
        Map<String, Object> map = Maps.newHashMap();
        map.put("channel", "edu");
        map.put("pn", 1);
        map.put("ps", 1000);
        map.put("clientNoList", new String[]{"offline"});
        GenericListResponse<OfflineProductDTO> response = productClient.productChannel(map);
        if (null == response
                || GenericListResponse.CODE_NG.equals(response.getCode())
                || CollectionUtils.isEmpty(response.getList())) {
            log.info("{}通过用户查询线下录入的产品列表异常", findCode);
            return GenericListResponse.listNoCount(retList);
        }

        //请求用户中心
        ResponseEntity<GenericDataResponse<Map<String, Object>>> responseEntity = userClient.queryUserRoleAndAuthority(userCode, SYS_CODE);
        log.debug("{} 查询用户分支机构及地区权限 用户中心返回值 jtBranchs = {}", findCode, JSON.toJSONString(responseEntity));
        LinkedHashMap<String, String> dataPopedom = (LinkedHashMap) responseEntity.getBody().getData().get("dataPopedom");
        // 获取区域码, 可能是城市码,省编码,  多个值是以逗号隔开
        String dataArea = dataPopedom.get("dataArea");
        String jtBranchs = dataPopedom.get("jtBranchs");

        //全国
        if ("000000".equals(jtBranchs) || "JT0000".equals(jtBranchs) || "000000".equals(dataArea)) {
            return GenericListResponse.listNoCount(response.getList());
        }
        List<String> dataAreaList = Lists.newArrayList();
        //添加地区权限 如果是区权限 添加市和省的，如果是市权限 添加省的
        for (String areaCode : dataArea.split(",")) {
            dataAreaList.add(areaCode);
            if (!"00".equals(areaCode.substring(4))) {
                dataAreaList.add(areaCode.substring(0, 2) + "0000");
                dataAreaList.add(areaCode.substring(0, 4) + "00");
            } else if (!"0000".equals(areaCode.substring(2))) {
                dataAreaList.add(areaCode.substring(0, 4) + "00");
            }
        }

        for (OfflineProductDTO offlineProductDTO : response.getList()) {
            //如果是广东营业部，特殊处理，将指定的产品添加到返回列表中
            if (OfflineGDProductEnum.contains(offlineProductDTO.getCode())
                    && jtBranchs.contains("JT0170001")) {
                retList.add(offlineProductDTO);
                continue;
            }
            for (AreaDto areaDto : offlineProductDTO.getAreaBeanList()) {
                //如果该产品的出单区域含有该用户的地区权限
                if ("000000".equals(areaDto.getAreaCode())
                        || dataAreaList.contains(areaDto.getAreaCode())) {
                    retList.add(offlineProductDTO);
                    break;
                }
            }
        }
        return GenericListResponse.listNoCount(retList);
    }

    /**
     * 推送投保信息到投保中心
     *
     * @return
     */
    public void pushPolicyToIns(String findCode, OfflineOrder offlineOrder) {
        //查询出所有未推送或推送失败的单子
        Weekend<OfflinePolicy> weekend = Weekend.of(OfflinePolicy.class);
        WeekendCriteria<OfflinePolicy, Object> criteria = weekend.weekendCriteria();
        criteria.andEqualTo(OfflinePolicy::getOrderId, offlineOrder.getId());
        //推送成功的不再推送
        criteria.andNotEqualTo(OfflinePolicy::getPushStatus, PushStatusEnum.SUCCESS.getCode());
        List<OfflinePolicy> offlinePolicyList = offlinePolicyMapper.selectByExample(weekend);
        for (OfflinePolicy offlinePolicy : offlinePolicyList) {
            String holderCode = offlinePolicy.getHolderCode();

            //得到投保人的userCode， 如果教育有记录，直接用本地的，如果没有注册记录，调用用户中心注册接口
            if (StringUtils.isBlank(offlinePolicy.getHolderCode())) {
                try {
                    holderCode = getHolderCode(offlineOrder, offlinePolicy);
                } catch (Exception e) {
                    updateOfflinePolicyPushStatus(offlinePolicy, PushStatusEnum.ERROR.getCode(), e.getMessage());
                    log.error("{}线下保单推送获取用户编码异常:{}", findCode, e);
                    continue;
                }
            }
            offlinePolicy.setHolderCode(holderCode);
            //推送前查询并添加推广人
            addMarketer(findCode, offlinePolicy, offlineOrder);
            try {
                //投保
                pushPolicyToIns(findCode, offlineOrder, offlinePolicy);
            } catch (Exception e) {
                updateOfflinePolicyPushStatus(offlinePolicy, PushStatusEnum.ERROR.getCode(), e.getMessage());
                log.error("{}线下保单推送异常:{}", findCode, e);
                continue;
            }
        }

    }

    /**
     * 线下投保
     *
     * @param offlineOrder
     * @param offlinePolicy
     */
    private void pushPolicyToIns(String findCode, OfflineOrder offlineOrder, OfflinePolicy offlinePolicy) throws Exception {
        // 遍历集合数据  组装调用  远程接口的报文 TbParamVO
        TbParamVO tbParamVO = new TbParamVO();
        tbParamVO.setEntryType("01");
        tbParamVO.setSource("00");
        tbParamVO.setOperator(offlineOrder.getOperatorNo());// 操作人员编码   前端传过来
        List<ContextApplicationForm> applicationForms = Lists.newArrayList();

        /**
         * 投保单信息
         */
        ContextApplicationForm contextApplicationForm = createInformation(offlineOrder, offlinePolicy);

        /**
         * 投保人信息
         */
        ContextHolder holder = createHolder(offlineOrder, offlinePolicy);
        contextApplicationForm.setPolicyHolder(holder);


        /**
         * 被保险人信息
         */
        List<ContextInsured> insureds = Lists.newArrayList();
        ContextInsured contextInsured = createContextInsured(offlineOrder, offlinePolicy);
        insureds.add(contextInsured);
        contextApplicationForm.setInsureds(insureds);


        //设置认领的扩展信息  认领
        contextApplicationForm = createContextClaim(contextApplicationForm,offlineOrder,offlinePolicy);

        /**
         * 险种信息
         */
        List<ContextRisk> risks = createContextRiskList(offlineOrder, offlinePolicy);
        contextApplicationForm.setRisk(risks);

        /**
         * 保单信息
         */
        ContextPolicy contextPolicy = createContextPolicy(offlineOrder, offlinePolicy);
        contextApplicationForm.setPolicy(contextPolicy);

        /**
         * 推广人员信息
         */
        ContextAgent agent = createContestAgent(offlinePolicy);
        contextApplicationForm.setAgents(Lists.newArrayList(agent));

        //如果是需要添加承保公司的 添加承保公司相关信息
        if (OfflineAddCompanyEnum.is(offlineOrder.getProductCode())) {
            /**
             * 承保公司
             */
            ContextInsuranceCompany insuranceCompany = createInsuranceCompany(offlineOrder);
            contextApplicationForm.setInsuranceCompanies(Lists.newArrayList(insuranceCompany));
        }




        applicationForms.add(contextApplicationForm);
        tbParamVO.setApplicationForms(applicationForms);
        // 去调投保接口
        String paramJson = JsonUtils.toJson(tbParamVO);

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (null == attributes) {
            return;
        }

        //添加reSub_Token
        String reSubToken = idgClient.getToken();
        FeignConfiguration.addHeader(FeignConfiguration.RE_SUB_TOKEN, reSubToken);
        log.info("线下保单录入,入参为"+paramJson);
        ResponseEntity<GenericDataResponse<Map<String, Object>>> genericDataResponseResponseEntity = insOrderClient.submitOrderOffline(paramJson, "edu");
        GenericDataResponse<Map<String, Object>> body = genericDataResponseResponseEntity.getBody();
        String code = body.getCode();
        log.info("{}调用投保接口返回信息{}：{}", findCode, code, JSON.toJSONString(body));
        if ("0000".equals(code)) {
            updateOfflinePolicyPushStatus(offlinePolicy, PushStatusEnum.SUCCESS.getCode(), "成功");
            //调用业绩相关
            Map<String, Object> data1 = (Map<String, Object>) body.getData().get("body");
            List<Object> information = (List<Object>) data1.get("applicationForms");
            Map<String, Object> data2 = (Map<String, Object>) information.get(0);
            String appCode = (String) ((Map<String, Object>) data2.get("information")).get("applicationFormCode");

            //投保成功后更新投保单号
            OfflinePolicy update = new OfflinePolicy();
            update.setId(offlinePolicy.getId());
            update.setAppCode(offlinePolicy.getAppCode());
            offlinePolicyMapper.updateByPrimaryKeySelective(update);
            //调用业管认领查询接口
            Map<String,Object> mhdsDitchList = sttlManClient.mhdsDitchSelectByPolicyNo(offlinePolicy.getPolicyNo(),
                   offlineOrder.getBranchCode(),
                    "7");
            log.info("业管认领查询返回数据",JsonUtils.toJson(mhdsDitchList));
            //未查询到
            if(!mhdsDitchList.get("code").equals("0000")){
               //修改保单号状态为无认领信息
                update.setClaimStatus(ClaimStatusEnum.DEFAULT.getCode());
                update.setClaimReason((String) mhdsDitchList.get("msg"));
                offlinePolicyMapper.updateByPrimaryKeySelective(update);
            }else{
                List<Map<String, String>> operparam = new ArrayList<>();
                Map<String,String> claimMessage = new HashMap<>();
                claimMessage.put("claimbyid",offlineOrder.getOperatorNo());//认领人id
                claimMessage.put("systemcode","7");//所属系统
                claimMessage.put("operby",offlineOrder.getOperatorName());//操作人
                claimMessage.put("orgcode",offlineOrder.getBranchCode());//机构编码
                claimMessage.put("policyno",offlinePolicy.getPolicyNo());// 保单号
                claimMessage.put("operbyid",offlineOrder.getOperatorNo());//操作人id
                claimMessage.put("claimby",offlineOrder.getOperatorName());//认领人
                operparam.add(claimMessage);
                log.info("调用业管认领参数: {} ",JsonUtils.toJson(operparam));
                //调用业管认领接口
                Map<String,Object> stringStringMap = sttlManClient.mhdsDitchClaim(operparam);
                log.info("业管认领接口返回数据",JsonUtils.toJson(stringStringMap));
                if(stringStringMap.get("executecode").equals("0")){
                    //认领成功，修改状态
                    update.setClaimStatus(ClaimStatusEnum.SUCCESS.getCode());
                    update.setClaimReason(null);
                }else{
                    //认领失败
                    update.setClaimStatus(ClaimStatusEnum.ERROR.getCode());
                    update.setClaimReason((String) stringStringMap.get("executenote"));
                }
                offlinePolicyMapper.updateByPrimaryKeySelective(update);
            }
            //佣金
            commissionService.createInsCommissionPush(findCode, appCode);
        } else {
            updateOfflinePolicyPushStatus(offlinePolicy, PushStatusEnum.ERROR.getCode(), body.getMsg());
        }
    }

    /**
     * 投保中心认领信息入参
     * @param offlineOrder
     * @param offlinePolicy
     * @return
     */
    private ContextApplicationForm createContextClaim(ContextApplicationForm contextApplicationForm,OfflineOrder offlineOrder, OfflinePolicy offlinePolicy) {
        //查询到该保单是否倒签
        if(offlinePolicy.getBackLog().equals(IsOrNotEnum.IS.getValue())){
            //  倒签原因
            if(!StringUtils.isEmpty(offlineOrder.getBacklogReason())){
                contextApplicationForm.setReasonForBacklog(BacklogReasonEnum.getDescByCode(offlineOrder.getBacklogReason()));
            }
        }
        //查询到该保单是否跨期
        if(offlinePolicy.getCrossTerm().equals(IsOrNotEnum.IS.getValue())){
            // 收入确认时间点
            if(offlineOrder.getIncomeConfirmTime() !=null){
                contextApplicationForm.setRevenueRecognitionTime(offlineOrder.getIncomeConfirmTime());
            }
            //  收入确认佐证原因
            if(offlineOrder.getEvidenceReason() !=null){
                contextApplicationForm.setRevenueRecognitionReason(EvidenceReasonEnum.getDescByCode(offlineOrder.getEvidenceReason()));
            }
            //revenueRecognitionOtherReason收入确认佐证其他原因
            if(offlineOrder.getOtherReason() !=null){
                contextApplicationForm.setRevenueRecognitionOtherReason(offlineOrder.getOtherReason());
            }
        }
        //revenueRecognitionFile 收入确认佐证文件
        if(offlineOrder.getEvidenceFile() !=null){
            List<AttachmentVO> attachmentVOS = new ArrayList<>(5);
            List<FileVO> policyFile;
            policyFile = JSON.parseArray(offlineOrder.getEvidenceFile(), FileVO.class);
            for (int i = 0; i < policyFile.size(); i++) {
                AttachmentVO attachmentVO = new AttachmentVO();
                attachmentVO.setId(policyFile.get(i).getFileId());
                attachmentVO.setType(BusinessTypeCodeEnum.F004.getCode());
                attachmentVOS.add(attachmentVO);
            }
            contextApplicationForm.setAttachments(attachmentVOS);
        }
        return contextApplicationForm;
    }

    /**
     * 承保公司
     */
    private ContextInsuranceCompany createInsuranceCompany(OfflineOrder offlineOrder) {
        ContextInsuranceCompany contextInsuranceCompany = new ContextInsuranceCompany();
        contextInsuranceCompany.setCode(offlineOrder.getInsCompanyCode());
        contextInsuranceCompany.setName(offlineOrder.getInsCompanyName());
        contextInsuranceCompany.setRole1("01");
        contextInsuranceCompany.setRole2("01");
        return contextInsuranceCompany;
    }

    /**
     * 推广人员信息
     */
    private ContextAgent createContestAgent(OfflinePolicy offlinePolicy) {
        ContextAgent agent = new ContextAgent();
        agent.setAgentCode(offlinePolicy.getMarketerUserCode());
        agent.setAgentName(offlinePolicy.getMarketerName());
        agent.setSmsAgentCode(offlinePolicy.getMarketerNo());
        agent.setBranchCode(offlinePolicy.getMarketerBranchCode());
        agent.setBranchName(offlinePolicy.getMarketerBranchName());
        agent.setChannelCode(offlinePolicy.getMarketerChannelCode());
        agent.setChannelName(offlinePolicy.getMarketerChannelName());
        return agent;
    }

    private ContextPolicy createContextPolicy(OfflineOrder offlineOrder, OfflinePolicy offlinePolicy) {
        ContextPolicy contextPolicy = new ContextPolicy();
        contextPolicy.setPolicyNo(offlinePolicy.getPolicyNo());
        contextPolicy.setPrem(offlinePolicy.getPremium());
        contextPolicy.setStartDate(offlinePolicy.getStartDate());
        contextPolicy.setEndDate(offlinePolicy.getEndDate());
        contextPolicy.setIssueDate(offlinePolicy.getInsureDate());
        contextPolicy.setInputDate(offlineOrder.getCreateTime());
        contextPolicy.setBranchCode(offlineOrder.getBranchCode());
        contextPolicy.setChannalCode("edu");
        contextPolicy.setInputPerson(offlineOrder.getOperatorNo());
        return contextPolicy;
    }

    private List<ContextRisk> createContextRiskList(OfflineOrder offlineOrder, OfflinePolicy offlinePolicy) throws Exception {
        List<ContextRisk> contextRiskList = Lists.newArrayList();
        // 根据产品编码查询该产品所有险种信息
        GenericListResponse<RiskDTO> productRisk = productClient.searchRiskDtoByProductCode(offlineOrder.getProductCode(), "edu");
        if (!"0000".equals(productRisk.getCode())) {
            throw new RuntimeException("通过产品查询险种失败!");
        } else {
            //将所有限额值  以riskCode为key 做整理
            Map<String, List<RiskDutyLimitVO>> orderRiskLimitsMap = parserOrderRiskLimit(offlineOrder.getRiskDutyLimit());
            //将产品的risk转成投保中心需要的risk
            ContextRiskMap contextRiskMap = ChangeUtils.toContextRiskMap(productRisk.getList());
            //取出所有的险种集合
            Map<String, ContextRisk> contextRisks = contextRiskMap.getContextRisks();
            //将保存的限额值 保存到险种信息中
            for (String riskCode : orderRiskLimitsMap.keySet()) {
                List<RiskDutyLimitVO> orderRiskDutyListVOs = orderRiskLimitsMap.get(riskCode);
                ContextRisk contextBaseRisk = contextRisks.get(riskCode);
                for (RiskDutyLimitVO riskDutyLimitVO : orderRiskDutyListVOs) {
                    LimitValue limitValue = contextRiskMap.getDutyLimitValues().get(riskDutyLimitVO.getLimitValueCode());
                    ChangeUtils.setLimitValue(contextBaseRisk, limitValue);
                }
                contextRiskList.add(contextBaseRisk);
            }
            //为所有险种添加保费信息  可能会有问题，因为线下业务 无法区分主险附加险
            for (ContextRisk contextRisk : contextRiskList) {
                contextRisk.setStartDate(offlinePolicy.getStartDate());
                contextRisk.setEndDate(offlinePolicy.getEndDate());
                //保费  主险保费
                contextRisk.setPrem(offlinePolicy.getPremium());
                //实付保费
                contextRisk.setActualPrem(offlinePolicy.getPremium());
                //优惠后
                contextRisk.setAfterPrem(offlinePolicy.getPremium());
                //优惠前保费
                contextRisk.setBeforePrem(offlinePolicy.getPremium());
                //优惠保费
                contextRisk.setReducePrem(BigDecimal.ZERO);
            }

        }
        return contextRiskList;
    }

    private Map<String, List<RiskDutyLimitVO>> parserOrderRiskLimit(String riskDutyLimit) {
        List<RiskDutyLimitVO> riskDutyLimitVOS = JSON.parseArray(riskDutyLimit, RiskDutyLimitVO.class);
        Map<String, List<RiskDutyLimitVO>> riskMap = Maps.newHashMap();
        for (RiskDutyLimitVO riskDutyLimitVO : riskDutyLimitVOS) {
            List<RiskDutyLimitVO> riskList =
                    null == riskMap.get(riskDutyLimitVO.getRiskCode()) ?
                            Lists.newArrayList() : riskMap.get(riskDutyLimitVO.getRiskCode());
            riskList.add(riskDutyLimitVO);
            riskMap.put(riskDutyLimitVO.getRiskCode(), riskList);
        }
        return riskMap;
    }


    /**
     * 通过id修改保单推送的状态及投保人的用户编码
     *
     * @param pushStatus
     * @param errorMsg
     */
    private void updateOfflinePolicyPushStatus(OfflinePolicy offlinePolicy, String pushStatus, String errorMsg) {
        offlinePolicy.setPushStatus(pushStatus);
        offlinePolicy.setErrorMsg(errorMsg);
        offlinePolicyMapper.updateByPrimaryKeySelective(offlinePolicy);
    }

    private ContextInsured createContextInsured(OfflineOrder offlineOrder, OfflinePolicy offlinePolicy) {
        ContextInsured contextInsured = new ContextInsured();
        contextInsured.setType(offlineOrder.getUserType());
        contextInsured.setProvinceCode(offlineOrder.getProvinceCode());
        contextInsured.setCityCode(offlineOrder.getCityCode());
        contextInsured.setBnfyOption("Y");
        contextInsured.setName(offlinePolicy.getInsuredName());
        contextInsured.setInsureYear(DateUtils.getYear(offlinePolicy.getInsureDate()).toString());
        return contextInsured;
    }

    /**
     * @param offlineOrder
     * @param offlinePolicy
     * @return
     */
    private ContextApplicationForm createInformation(OfflineOrder offlineOrder, OfflinePolicy offlinePolicy) {
        ContextApplicationForm information = new ContextApplicationForm();
        //线下channelType 0001
        information.setChannelType("0001");
        information.setApplicationType("01");
        information.setEndDate(DateUtils.converDate(offlinePolicy.getEndDate()));
        information.setCityCode(offlineOrder.getCityCode());
        information.setRenewalTimes(0);
        String proCode = offlineOrder.getProductCode();
        information.setProductName(offlineOrder.getProductName());
        information.setPolicyKind("00");
        information.setCityName(offlineOrder.getCityName());
        information.setProjectCode(offlineOrder.getProjectCode());
        information.setProjectName(offlineOrder.getProjectName());
        information.setTerm(DateUtils.calculatedDays(offlinePolicy.getEndDate(), offlinePolicy.getStartDate()));
        information.setProductType("00");
        information.setCountyName(offlineOrder.getCountyName());
        information.setIsRenewal("N");
        information.setProvinceCode(offlineOrder.getProvinceCode());
        information.setChannalCode("edu");
        information.setConsignor(offlinePolicy.getCustomerName());
        information.setBranchCode(offlineOrder.getBranchCode());
        information.setBranchName(offlineOrder.getBranchName());
        information.setCountyCode(offlineOrder.getCountyCode());
        information.setCityCode(offlineOrder.getCityCode());
        information.setCityName(offlineOrder.getCityName());
        information.setProductCode(proCode);
        information.setOriginalStatus("");
        information.setProvinceCode(offlineOrder.getProvinceCode());
        information.setProvinceName(offlineOrder.getProvinceName());
        information.setStartDate(DateUtils.converDate(offlinePolicy.getStartDate()));
        information.setRenewalLastPolicyNo("");
        information.setApplicationDate(DateUtils.converDate(offlinePolicy.getInsureDate()));// 投保日期 默认当前
        information.setPrem(offlinePolicy.getPremium());
        information.setInsuredCount(offlinePolicy.getInsuredCount());

        return information;
    }


    private ContextHolder createHolder(OfflineOrder offlineOrder, OfflinePolicy offlinePolicy) {
        ContextHolder holder = new ContextHolder();
        holder.setType(offlineOrder.getUserType());
        //如果没有手机号  就使用操作人的手机号当投保人手机号
        if (StringUtils.isNotBlank(offlinePolicy.getHolderPhone())) {
            holder.setPhone(offlinePolicy.getHolderPhone());
        } else {
            holder.setPhone(offlineOrder.getOperatorPhone());
        }
        holder.setName(offlinePolicy.getHolderName());
        holder.setHolderCode(offlinePolicy.getHolderCode());
        return holder;
    }

}
